import datetime
import threading
import cv2
from queue import Queue,Full

class VideoStream:
    def __init__(self, url) -> None:
        self.url = url
        self.stop_event = threading.Event()  # 新增退出标志
        self.stop_event.clear()

        self.vid_cap = cv2.VideoCapture(self.url)
        self.frame_queue = Queue(maxsize=8)  # 限制队列大小
        self.capture_thread = threading.Thread(target=self.capture_frames,daemon=True)
        self.capture_thread.start()
        self.current_time = None

    def capture_frames(self):
        """获取帧放进队列"""
        while not self.stop_event.is_set() and self.vid_cap.isOpened():
            ret, frame = self.vid_cap.read()
            if ret:
                frame = cv2.resize(frame, (640, 480))
                frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                try:
                    # 设置超时避免永久阻塞
                    self.frame_queue.put(frame_rgb, block=False, timeout=3)
                    del frame, frame_rgb

                except Full:
                    if self.stop_event.is_set():
                        print("流关闭：触发事件")
                        break  # 若已触发退出，则直接退出
            else:
                self.frame_queue.put(None)
                break

    def reload(self):
        print("""重启视频流""")

        self.close_stream()
        self.vid_cap = cv2.VideoCapture(self.url)
        self.capture_thread = threading.Thread(target=self.capture_frames)
        self.capture_thread.start()

    def get_frame(self):
        """获取一帧"""
        if self.frame_queue.qsize()>0:
            res = self.frame_queue.get(block=False,timeout=3)  # 无阻塞
            if res is None:
                print("未获取到帧")
                res = self.frame_queue.get(block=False,timeout=3)
                if res is None:
                    print("未获取到帧")
                    self.close_stream()
            return res
        else:
            return None

    def close_stream(self):
        """关闭视频流"""
        print("视频流关闭调用")
        self.stop_event.set()  # 设置退出标志
        if self.capture_thread.is_alive():
            self.capture_thread.join(timeout=2)  # 等待线程退出
        if self.vid_cap.isOpened():
            self.vid_cap.release()
        cv2.destroyAllWindows()

    def display_stream(self):
        """test"""
        try:
            while True:
                frame = self.get_frame()
                if frame is not None:
                    cv2.imshow("Video Stream", frame)
                    if cv2.waitKey(1) & 0xFF == ord("q"):
                        break
        finally:
            self.close_stream()
